import json
import re
from django.conf import settings
from django.contrib.auth import login, logout
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpResponse, JsonResponse
from django.views import View
import os
from utils.loading_html import load_html
from fdfs_client.client import Fdfs_client

from utils.response_code import *
from django_redis import get_redis_connection
from users.models import User


class LoadRegisterView(View):

    def get(self, request):
        """加载注册页面"""

        return HttpResponse(load_html('/static/register.html'), status=200)


class RegisterView(View):

    def post(self, request):
        """处理用户注册"""

        # 获取数据
        recv_data = json.loads(request.body)
        mobile = recv_data.get('mobile')
        phonecode = recv_data.get('phonecode')
        password = recv_data.get('password')

        # 校验参数是否缺失
        if not all([mobile, phonecode, password]):
            return JsonResponse({
                'errno': RET.NECESSARYPARAMERR,
                'errmsg': error_map[RET.NECESSARYPARAMERR]
            })

        # 校验手机格式
        if not re.match(r'1[35678]\d{9}$', mobile):
            return JsonResponse({
                'errno': RET.MOBILEERR,
                'errmsg': error_map[RET.MOBILEERR]
            })

        # 验证短信验证码
        redis_client = get_redis_connection('verify')
        sms_code = redis_client.get('sms_code_{}'.format(mobile))
        if sms_code:
            sms_code = sms_code.decode()
        if phonecode != sms_code:
            return JsonResponse({
                'errno': RET.PARAMERR,
                'errmsg': error_map[RET.PARAMERR]
            })
        redis_client.delete('sms_code_{}'.format(mobile))

        # 用户是否已注册
        try:
            user = User.objects.get(mobile=mobile)
            return JsonResponse({
                'errno': RET.DATAEXIST,
                'errmsg': error_map[RET.DATAEXIST]
            })
        except:
            pass

        # 创建用户
        user = User.objects.create_user(
            username=mobile,
            mobile=mobile,
            password=password
        )

        # 返回响应
        return JsonResponse({
            'errno': RET.OK,
            'errmsg': '注册成功'
        })


class LoadHomeView(View):
    def get(self, request):
        """加载主页"""
        return HttpResponse(load_html('/static/index.html'), status=200)


class LoadLoginView(View):

    def get(self, request):
        """加载登录页面"""
        return HttpResponse(load_html('/static/login.html'), status=200)


class LoginView(View):

    def post(self, request):
        """用户登录"""

        # 获取数据
        recv_data = json.loads(request.body)
        mobile = recv_data.get('mobile')
        password = recv_data.get('password')

        # 校验数据
        if not all([mobile, password]):
            return JsonResponse({
                'errno': RET.NECESSARYPARAMERR,
                'errmsg': error_map[RET.NECESSARYPARAMERR]
            })

        # 检测用户是否注册
        try:
            user = User.objects.get(mobile=mobile)
        except:
            return JsonResponse({
                'errno': RET.USERERR,
                'errmsg': error_map[RET.USERERR]
            })

        # 校验密码
        if not user.check_password(raw_password=password):
            return JsonResponse({
                'errno': RET.PWDERR,
                'errmsg': error_map[RET.PWDERR]
            })

        # 登录用户
        login(request, user)

        # 返回响应
        return JsonResponse({
            'errno': '0',
            'errmsg': '登录成功'
        })

    def get(self, request):
        """判断用户是否登录"""

        user = request.user
        if user.is_authenticated:
            return JsonResponse({
                'errno': RET.OK,
                'errmsg': '已登录',
                'data': {
                    'user_id': user.id,
                    'name': user.username
                }
            })
        else:
            return JsonResponse({
                'errno': RET.SESSIONERR,
                'errmsg': error_map[RET.SESSIONERR]
            })

    def delete(self, request):
        """用户退出登录"""

        # 登出
        logout(request)

        # 返回响应
        return JsonResponse({
            'errno': 0,
            'errmsg': '已登出'
        })


class LoadUserCenterView(LoginRequiredMixin, View):
    def get(self, request):
        """加载用户中心页面"""
        return HttpResponse(load_html('/static/my.html'), status=200)


class UserCenterView(LoginRequiredMixin, View):
    def get(self, request):
        """用户个人信息"""

        user = request.user
        avatar = user.avatar.url
        if not avatar:
            avatar = ''

        user_data = {
            'avatar_url': avatar,
            'create_time': user.create_time,
            'mobile': user.mobile,
            'name': user.username,
            'user_id': user.id
        }

        return JsonResponse({
            'errno': RET.OK,
            'errmsg': error_map[RET.OK],
            'data': user_data
        })


class LoadUserInfoView(LoginRequiredMixin, View):
    def get(self, request):
        """加载个人信息编辑页面"""

        return HttpResponse(load_html('/static/profile.html'), status=200)


class UploadAvatarView(LoginRequiredMixin, View):
    def post(self, request):
        """上传头像"""

        # 接受数据
        avatar = request.FILES.get('avatar')

        # 校验数据
        if not avatar:
            return JsonResponse({
                'errno': RET.NECESSARYPARAMERR,
                'errmsg': error_map[RET.NECESSARYPARAMERR]
            })

        # 上传头像
        fdfs_client = Fdfs_client(settings.BASE_DIR + '/utils/fdfs/client.conf')
        avatar_buffer = avatar.read()
        result = fdfs_client.upload_by_buffer(avatar_buffer)

        # 判断是否上传成功
        if result['Status'] != 'Upload successed.':
            return JsonResponse({
                'errno': RET.THIRDERR,
                'errmsg': error_map[RET.THIRDERR]
            })

        # 写入数据库
        avatar_url = result['Remote file_id']
        user = request.user
        user.avatar = avatar_url
        user.save()

        # 返回响应
        return JsonResponse({
            'errno': 0,
            'errmsg': '头像上传成功',
            'data': {
                'avatar_url': settings.BASE_URL + avatar_url
            }
        })


class ModifyUserNameView(LoginRequiredMixin, View):
    def put(self, request):
        """修改用户名"""

        # 获取数据
        name = json.loads(request.body).get('name')
        user = request.user

        # 校验数据
        if not name:
            return JsonResponse({
                'errno': RET.PARAMERR,
                'errmsg': error_map[RET.PARAMERR]
            })

        # 修改用户名
        user.username = name
        user.save()

        # 返回响应
        return JsonResponse({
            'errno': 0,
            'errmsg': '修改成功'
        })


class LoadUserRealNameAuthenticationView(View):
    def get(self, request):
        """加载实名认证页面"""

        return HttpResponse(load_html('/static/auth.html'), status=200)


class UserRealNameAuthenticationView(View):

    def get(self, request):
        """判断用户是否实名认证"""

        # 判断用户是否登录
        user = request.user
        if not user.is_authenticated:
            return JsonResponse({
                'errno': RET.SESSIONERR,
                'errmsg': error_map[RET.SESSIONERR]
            })

        # 判断是否实名认证
        real_name = user.real_name
        id_card = user.id_card

        if real_name and id_card:
            return JsonResponse({
                'errno': 0,
                'errmsg': '已认证',
                'data': {
                    'real_name': real_name,
                    'id_card': id_card
                }
            })

        else:
            return JsonResponse({
                'errno': 9999,
                'errmsg': '用户未认证'
            })

    def post(self, request):
        """实名认证"""

        # 判断用户是否登录
        user = request.user
        if not user.is_authenticated:
            return JsonResponse({
                'errno': RET.SESSIONERR,
                'errmsg': error_map[RET.SESSIONERR]
            })

        # 接收数据
        real_name = json.loads(request.body).get('real_name')
        id_card = json.loads(request.body).get('id_card')

        # 校验是否缺失参数
        if not all([real_name, id_card]):
            return JsonResponse({
                'errno': RET.PARAMERR,
                'errmsg': error_map[RET.PARAMERR]
            })

        # 保存用户实名信息
        user.real_name = real_name
        user.id_card = id_card
        user.save()

        # 返回响应
        return JsonResponse({
            'errno': 0,
            'errmsg': '认证信息保存成功',
            'data': {
                'real_name': real_name,
                'id_card': id_card
            }
        })